package com.authine.cloudpivot.ext.controller;

import com.alibaba.fastjson.JSONObject;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectCreatedModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkItemModel;
import com.authine.cloudpivot.engine.api.model.runtime.WorkflowInstanceModel;
import com.authine.cloudpivot.engine.enums.status.SequenceStatus;
import com.authine.cloudpivot.ext.Utils.CustomSchemaCode;
import com.authine.cloudpivot.ext.Utils.Utils;
import com.authine.cloudpivot.ext.service.CloudSqlService;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 场地信息表
 */
@Slf4j
@RestController
@RequestMapping("/public/PlaceInformationController")
public class PlaceInformationController extends BaseController {

    @Autowired
    private AttributeController attributeController;

    @Autowired
    CloudSqlService sqlService;

    /**
     * 获取管理员
     *
     * @return
     */
    @PostMapping("/getAdministrator")
    public Map<String, Object> test(@RequestBody Map<String, String> map) {

        String administrator = map.get("administrator");//管理员名称
        this.validateNotEmpty(administrator, "管理员名称不能为空");
        String postANumber = map.get("postANumber");//岗A代码
        String postBNumber = map.get("postBNumber");//岗B代码

        List<Map<String, Object>> postAListA = new ArrayList<>();
        List<Map<String, Object>> postAListB = new ArrayList<>();
        List<Map<String, Object>> postBListA = new ArrayList<>();
        List<Map<String, Object>> postBListB = new ArrayList<>();
        Map<String, Object> returnMap = new HashMap<>();

        List<Map<String, Object>> dataByPostA = attributeController.getDataByPost(postANumber);
        if (dataByPostA != null) {
            String administratorAName = administrator.split("、")[0];
            String postA_A = administratorAName.split("（")[0];//岗A-A
            log.info("岗A管理员-A：{}", postA_A);
            dataByPostA.stream().forEach(data -> {
                String name = (String) data.get("name");
                if (postA_A.contains(name)) {
                    postAListA.add(data);
                }
            });

            int i1 = administratorAName.indexOf("（");
            int i2 = administratorAName.indexOf("）");
            if (i1 > 0 && i2 > 0) {
                //进入此方法说明岗A管理员-B存在
                String postA_B = administratorAName.substring(i1);
                log.info("岗A管理员-B：{}", postA_B);
                dataByPostA.stream().forEach(data -> {
                    String name = (String) data.get("name");
                    if (postA_B.contains(name)) {
                        postAListB.add(data);
                    }
                });
            }

        }

        List<Map<String, Object>> dataByPostB = attributeController.getDataByPost(postBNumber);
        if (dataByPostB != null && administrator.contains("、")) {
            String administratorBName = administrator.split("、")[1];
            String postB_A = administratorBName.split("（")[0];//岗B-A
            log.info("岗B管理员-A：{}", postB_A);
            dataByPostB.stream().forEach(data -> {
                String name = (String) data.get("name");
                if (postB_A.contains(name)) {
                    postBListA.add(data);
                }
            });

            int i1 = administratorBName.indexOf("（");
            int i2 = administratorBName.indexOf("）");
            if (i1 > 0 && i2 > 0) {
                //进入此方法说明岗A管理员-B存在
                String postB_B = administratorBName.substring(i1);
                log.info("岗B管理员-B：{}", postB_B);
                dataByPostB.stream().forEach(data -> {
                    String name = (String) data.get("name");
                    if (postB_B.contains(name)) {
                        postBListB.add(data);
                    }
                });
            }
        }

        returnMap.put("postAlistA", postAListA);
        if (CollectionUtils.isEmpty(postAListB)) {
            returnMap.put("postAListB", postAListA);
        } else {
            returnMap.put("postAListB", postAListB);
        }
        returnMap.put("postBlistA", postBListA);
        if (CollectionUtils.isEmpty(postBListB)) {
            returnMap.put("postBListB", postBListA);
        } else {
            returnMap.put("postBListB", postBListB);
        }
        return returnMap;
    }

    /**
     * 场地信息表  审批流完成后 数据写到-待完成工作清单 基础表，补全基础表的数据
     */
    @RequestMapping("finish")
    public void finish(String bizId) {

        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.placeInformation, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.placeInformationDetail);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        String approval = "";
//        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        for (Map<String, Object> map : list) {

            try {
//                Map<String, Object> data = fileInfoBaseMap(map, now, approval);

                Map<String, Object> data = Utils.fileInfoBaseMap(map, approval);
                data.put("auditDate", now);//审批时间
                //将子表中数据处理，随后更新至【场地信息表 基础表】，需要判断是否存在
                String id = existsBizObject(map);
                if (StringUtils.isNotBlank(id)) {
                    data.put("id", id);
                }

                log.info("场地信息表将要更新到基础表的数据：{}", JSONObject.toJSONString(data));
                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.placeInformationBase, data, false);
                model.setSequenceStatus(SequenceStatus.COMPLETED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("场地信息基础表-新增成功 ");
                //调用存储过程，入参id是指 待完成工作清单 基础表的表单id，每一条待完成工作清单的子表数据都会生成一条 待完成工作清单 基础表 的主表数据
                callProcess(id);

            } catch (Exception e) {
                log.info("场地信息基础表-操作失败");
                log.info(e.getMessage(), e);
            }

        }
    }

    @RequestMapping("toVoid")
    public void toVoid(String bizId) {
        BizObjectCreatedModel bizObject = getBizObjectFacade().getBizObject(CustomSchemaCode.toVoidPlaceInformation, bizId);
        List<Map<String, Object>> list = (List<Map<String, Object>>) bizObject.get(CustomSchemaCode.toVoidPlaceInformationDetail);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        //获取审批人
        String approval = getFileBaseInfoWorkFlowApproval(bizObject);
        for (Map<String, Object> map : list) {
            try {
                String id = existsBizObject(map);
                //判断是否已存在，如果不存在，放弃这条数据，直接跳过此次循环
                if (StringUtils.isBlank(id)) {
                    continue;
                }

                //获取数据
                Map<String, Object> data = fileInfoBaseMap(map, now, approval);
                data.put("id", id);

                BizObjectCreatedModel model = new BizObjectCreatedModel(CustomSchemaCode.placeInformationBase, data, false);
                model.setSequenceStatus(SequenceStatus.CANCELED.name());
                id = getBizObjectFacade().saveBizObject(CustomSchemaCode.adminUserId, model, false);
                log.info("场地信息基础表  作废操作成功 ");
                //调用存储过程
                callProcessToVoid(id);

            } catch (Exception e) {
                log.info("场地信息基础表-操作失败");
                log.info(e.getMessage(), e);
            }

        }
    }

    /**
     * 查询审批人,返回  员工号+姓名
     *
     * @param bizObject
     * @return
     */
    private String getFileBaseInfoWorkFlowApproval(BizObjectCreatedModel bizObject) {
        WorkflowInstanceModel instanceModel = getWorkflowInstanceFacade().getByObjectId(bizObject.getId());
        List<WorkItemModel> workItems = getWorkflowInstanceFacade().getWorkItems(instanceModel.getId(), true);
        final String finalActivityCode = "Activity21";
        Optional<WorkItemModel> first = workItems.stream().filter(a -> a.getActivityCode().equals(finalActivityCode)).findFirst();
        String participant = null;
        if (first.isPresent()) {
            WorkItemModel workItemModel = first.get();
            participant = workItemModel.getParticipant();
        }


        if (participant == null) {
            participant = bizObject.getCreater().getId();
        }

        UserModel user = getOrganizationFacade().getUser(participant);


        return new StringBuilder(user.getEmployeeNo()).append("　").append(user.getName()).toString();
    }


    /**
     * 判断是否已存在
     *
     * @return
     */
    private String existsBizObject(Map data) {

//        //事项基础表id映射
//        String eventObjectId = (String) data.get("relevancePlaceCodeId");
        String placeCode = (String) data.get("placeCode");
        //场地代码关联
        log.info("relevancePlaceCode:{}", data.get("relevancePlaceCode"));

        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.placeInformationBase);

        StringBuilder sql = new StringBuilder("select id  from ").append(tableName).append(" where placeCode ='").append(placeCode).append("' ORDER BY createdTime desc limit 1");

        Map<String, Object> map = sqlService.getMap(sql.toString());

        return (String) map.get("id");
    }

    /**
     * 转换成  待完成工作清单 基础表 的数据
     *
     * @param map
     * @param auditDate
     * @return
     */
    private Map<String, Object> fileInfoBaseMap(Map<String, Object> map, String auditDate, String approval) {
        Map<String, Object> data = new HashMap<>();
        data.put("placeCode", map.get("placeCode"));

        data.put("relevanceSuperPlaceCode", map.get("relevanceSuperPlaceCode"));//上级场地代码关联
        data.put("superPlaceCode", map.get("superPlaceCode"));//上级场地代码隐藏
        data.put("superPlaceName", map.get("superPlaceName"));//上级场地名称
        data.put("superPlaceAdminDeptCode", map.get("superAdminDeptFNumber"));//上级场地管理部门代码

        data.put("placeName", map.get("placeName"));//场地名称

        data.put("company", map.get("company"));//公司fid
        data.put("companyNumber", map.get("companyNumber"));//公司代码
        data.put("companyName", map.get("companyName"));//公司名称

        data.put("adminDeptFid", map.get("adminDeptFid"));//管理部门代码
        data.put("adminDeptFNumber", map.get("adminDeptFNumber"));//管理部门代码隐藏
        data.put("adminDeptName", map.get("adminDeptName"));//管理部门
        data.put("advicerNumber", map.get("advicerNumber"));//意见人代码
        data.put("advicerName", map.get("advicerName"));//意见人

        data.put("relevancePostA", map.get("relevancePostA"));
        data.put("postANumber", map.get("postANumber"));
        data.put("postAName", map.get("postAName"));
        data.put("relevancePostB", map.get("relevancePostB"));
        data.put("postBNumber", map.get("postBNumber"));
        data.put("postBName", map.get("postBName"));

        data.put("administrator", map.get("administrator"));
        data.put("identification", map.get("identification"));
        data.put("relevanceSupervisoryDept", map.get("relevanceSupervisoryDept"));//监管部门代码
        data.put("supervisoryDeptFNumber", map.get("supervisoryDeptFNumber"));//监管部门代码隐藏
        data.put("supervisoryDeptName", map.get("supervisoryDeptName"));//监管部门
        data.put("description", map.get("description"));//description
        //审批时间
        data.put("auditDate", auditDate);
        //审批人
        data.put("approval", approval);
        return data;
    }

    /**
     * ----场地信息记录
     * exec   SyncSiteInfo
     *
     * @SiteCode nvarchar(100),        ----场地代码
     * @Upcode nvarchar(100),        ----上级场地代码
     * @SiteName nvarchar(200),        ----场地名称
     * @Companyid nvarchar(100),        ----公司ID
     * @ManDeptID nvarchar(100),        ----管理部门ID
     * @PosACode nvarchar(50),        ----岗A代码
     * @PosBCode nvarchar(50),        ----岗B代码
     * @Note nvarchar(100),        ----管理员
     * @Sign nvarchar(500),        ----标识
     * @SupDeptID nvarchar(100),        ----监管部门ID
     * @Desc nvarchar(300),        ----说明
     * @auditor nvarchar(50)        ----审批人	02.0100 张三
     */
    private void callProcess(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.placeInformationBase);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());

        log.info("场地信息记录-callProcess-入参map={}", JSONObject.toJSONString(map));

        //调用存储过程
        String placeCode = MapUtils.getString(map, "placeCode", "");
        String superPlaceCode = MapUtils.getString(map, "superPlaceCode", "");
        String placeName = MapUtils.getString(map, "placeName", "");


        String company = MapUtils.getString(map, "company", "");//公司FID
        String adminDeptFid = MapUtils.getString(map, "adminDeptFid", "");
        String postANumber = MapUtils.getString(map, "postANumber", "");
        String postBNumber = MapUtils.getString(map, "postBNumber", "");
        String administrator = MapUtils.getString(map, "administrator", "");
        String identification = MapUtils.getString(map, "identification", "");
        identification = identification.replace("'", "''");//标识
        String relevanceSupervisoryDept = MapUtils.getString(map, "relevanceSupervisoryDept", "");
        String description = MapUtils.getString(map, "description", "");
        String approval = MapUtils.getString(map, "approval", "");//审批人   02.0100 张三

        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SyncSiteInfo '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s'",
                placeCode, superPlaceCode, placeName, company, adminDeptFid, postANumber, postBNumber, administrator, identification, relevanceSupervisoryDept, description, approval);
        log.info("\n==========准备调用[场地信息记录]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[场地信息记录]存储过程执行完成");
    }

    /**
     * ----场地信息记录   作废
     * exec   SiteInfoDisable
     *
     * @SiteCode nvarchar(100)     ----场地代码
     */
    private void callProcessToVoid(String bizId) {

        if (StringUtils.isEmpty(bizId)) {
            return;
        }
        //编写sql
        String tableName = getBizObjectFacade().getTableName(CustomSchemaCode.placeInformationBase);
        StringBuilder sql = new StringBuilder("SELECT * from ")
                .append(tableName).append(" where id ='")
                .append(bizId).append("';");
        //查询到入参
        Map<String, Object> map = sqlService.getMap(sql.toString());
        log.info("入参map={}", map);

        //准备调用存储过程的入参
        String placeCode = MapUtils.getString(map, "placeCode", "");//fid
        String execSql = String.format("exec [HG_LINK].[hg].[dbo].SiteInfoDisable '%s'", placeCode);
        log.info("\n==========准备调用[场地信息记录   作废]存储过程:{}", execSql);
        sqlService.execute(CloudSqlService.htEas, execSql);
        log.info("\n=============[场地信息记录   作废]存储过程执行完成");

    }

}
